home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / TrackObject.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  69.9 KB  |  2,318 lines  |  [TEXT/KAHL]

  1. /* TrackObject.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "TrackObject.h"
  31. #include "TrackWindow.h"
  32. #include "TrackList.h"
  33. #include "Memory.h"
  34. #include "DataMunging.h"
  35. #include "Array.h"
  36. #include "FrameObject.h"
  37. #include "Screen.h"
  38. #include "TrackView.h"
  39. #include "NoteObject.h"
  40. #include "Menus.h"
  41. #include "BufferedFileInput.h"
  42. #include "BufferedFileOutput.h"
  43. #include "BinaryCodedDecimal.h"
  44. #include "LoadSaveNoteVectors.h"
  45.  
  46.  
  47. struct TrackObjectRec
  48.     {
  49.         MyBoolean                                DataModified;
  50.  
  51.         char*                                        Name;
  52.  
  53.         /* defaults for per-note parameters */
  54.         double                                    DefaultEarlyLateAdjust;
  55.         double                                    DefaultReleasePoint1;
  56.         unsigned long                        DefaultReleasePoint1ModeFlag;
  57.         double                                    DefaultReleasePoint2;
  58.         unsigned long                        DefaultReleasePoint2ModeFlag;
  59.         double                                    DefaultOverallLoudness;
  60.         double                                    DefaultStereoPositioning;
  61.         double                                    DefaultSurroundPositioning;
  62.         double                                    DefaultAccent1;
  63.         double                                    DefaultAccent2;
  64.         double                                    DefaultAccent3;
  65.         double                                    DefaultAccent4;
  66.         double                                    DefaultPitchDisplacementDepthAdjust;
  67.         unsigned long                        DefaultPitchDisplacementDepthAdjustModeFlag;
  68.         double                                    DefaultPitchDisplacementRateAdjust;
  69.         double                                    DefaultPitchDisplacementStartPoint;
  70.         unsigned long                        DefaultPitchDisplacementStartPointModeFlag;
  71.         double                                    DefaultHurryUpFactor;
  72.         double                                    DefaultDetune;
  73.         unsigned long                        DefaultDetuneModeFlag;
  74.         double                                    DefaultDuration;
  75.         unsigned long                        DefaultDurationModeFlag;
  76.         char*                                        PostProcessingFormula;
  77.         MyBoolean                                PostProcessingEnable;
  78.  
  79.         MyBoolean                                IncludeThisTrackInFinalPlayback;
  80.  
  81.         char*                                        InstrumentName;
  82.         ArrayRec*                                FrameArray;
  83.         ArrayRec*                                DependentViews;
  84.         ArrayRec*                                BackgroundObjects;
  85.  
  86.         MenuItemType*                        TrackMenuItem;
  87.         TrackWindowRec*                    TrackWindow;
  88.  
  89.         struct CodeCenterRec*        CodeCenter;
  90.         struct MainWindowRec*        MainWindow;
  91.         TrackListRec*                        TrackList;
  92.  
  93.         short                                        SavedWindowXLoc;
  94.         short                                        SavedWindowYLoc;
  95.         short                                        SavedWindowWidth;
  96.         short                                        SavedWindowHeight;
  97.     };
  98.  
  99.  
  100. /* create a new empty track object */
  101. TrackObjectRec*                NewTrackObject(struct CodeCenterRec* CodeCenter,
  102.                                                 struct MainWindowRec* MainWindow, struct TrackListRec* TrackList)
  103.     {
  104.         TrackObjectRec*            TrackObj;
  105.         char*                                NullTerminated;
  106.  
  107.         TrackObj = (TrackObjectRec*)AllocPtrCanFail(sizeof(TrackObjectRec),"TrackObjectRec");
  108.         if (TrackObj == NIL)
  109.             {
  110.              FailurePoint1:
  111.                 return NIL;
  112.             }
  113.         TrackObj->Name = StringToBlockCopy("untitled");
  114.         if (TrackObj->Name == NIL)
  115.             {
  116.              FailurePoint2:
  117.                 ReleasePtr((char*)TrackObj);
  118.                 goto FailurePoint1;
  119.             }
  120.         TrackObj->InstrumentName = AllocPtrCanFail(0,"TrackObjInstrumentName");
  121.         if (TrackObj->InstrumentName == NIL)
  122.             {
  123.              FailurePoint3:
  124.                 ReleasePtr(TrackObj->Name);
  125.                 goto FailurePoint2;
  126.             }
  127.         TrackObj->FrameArray = NewArray();
  128.         if (TrackObj->FrameArray == NIL)
  129.             {
  130.              FailurePoint4:
  131.                 ReleasePtr(TrackObj->InstrumentName);
  132.                 goto FailurePoint3;
  133.             }
  134.         TrackObj->DependentViews = NewArray();
  135.         if (TrackObj->DependentViews == NIL)
  136.             {
  137.              FailurePoint5:
  138.                 DisposeArray(TrackObj->FrameArray);
  139.                 goto FailurePoint4;
  140.             }
  141.         TrackObj->BackgroundObjects = NewArray();
  142.         if (TrackObj->BackgroundObjects == NIL)
  143.             {
  144.              FailurePoint6:
  145.                 DisposeArray(TrackObj->DependentViews);
  146.                 goto FailurePoint5;
  147.             }
  148.         NullTerminated = BlockToStringCopy(TrackObj->Name);
  149.         if (NullTerminated == NIL)
  150.             {
  151.              FailurePoint7:
  152.                 DisposeArray(TrackObj->BackgroundObjects);
  153.                 goto FailurePoint6;
  154.             }
  155.         TrackObj->TrackMenuItem = MakeNewMenuItem(
  156.             TrackListGetTrackMenu(TrackList),NullTerminated,0);
  157.         ReleasePtr(NullTerminated);
  158.         if (TrackObj->TrackMenuItem == NIL)
  159.             {
  160.              FailurePoint8:
  161.                 goto FailurePoint7;
  162.             }
  163.         TrackObj->PostProcessingFormula = StringToBlockCopy("#channel postprocessing\x0a");
  164.         if (TrackObj->PostProcessingFormula == NIL)
  165.             {
  166.              FailurePoint9:
  167.                 KillMenuItem(TrackObj->TrackMenuItem);
  168.                 goto FailurePoint8;
  169.             }
  170.         SetTag(TrackObj->PostProcessingFormula,"PostProcessingFormula");
  171.  
  172.         TrackObj->DataModified = False;
  173.         TrackObj->TrackWindow = NIL;
  174.         TrackObj->CodeCenter = CodeCenter;
  175.         TrackObj->MainWindow = MainWindow;
  176.         TrackObj->TrackList = TrackList;
  177.         TrackObj->IncludeThisTrackInFinalPlayback = True;
  178.  
  179.         TrackObj->DefaultEarlyLateAdjust = 0;
  180.         TrackObj->DefaultReleasePoint1 = 0;
  181.         TrackObj->DefaultReleasePoint1ModeFlag = eRelease1FromStart;
  182.         TrackObj->DefaultReleasePoint2 = 0;
  183.         TrackObj->DefaultReleasePoint2ModeFlag = eRelease2FromStart;
  184.         TrackObj->DefaultOverallLoudness = 1;
  185.         TrackObj->DefaultStereoPositioning = 0;
  186.         TrackObj->DefaultSurroundPositioning = 0;
  187.         TrackObj->DefaultAccent1 = 0;
  188.         TrackObj->DefaultAccent2 = 0;
  189.         TrackObj->DefaultAccent3 = 0;
  190.         TrackObj->DefaultAccent4 = 0;
  191.         TrackObj->DefaultPitchDisplacementDepthAdjust = 1;
  192.         TrackObj->DefaultPitchDisplacementDepthAdjustModeFlag = ePitchDisplacementDepthModeHalfSteps;
  193.         TrackObj->DefaultPitchDisplacementRateAdjust = 1;
  194.         TrackObj->DefaultPitchDisplacementStartPoint = 0;
  195.         TrackObj->DefaultPitchDisplacementStartPointModeFlag = ePitchDisplacementStartFromStart;
  196.         TrackObj->DefaultHurryUpFactor = 1;
  197.         TrackObj->DefaultDetune = 0;
  198.         TrackObj->DefaultDetuneModeFlag = eDetuningModeHalfSteps;
  199.         TrackObj->DefaultDuration = 0;
  200.         TrackObj->DefaultDurationModeFlag = eDurationAdjustAdditive;
  201.         TrackObj->PostProcessingEnable = False;
  202.  
  203.         TrackObj->SavedWindowXLoc = 0;
  204.         TrackObj->SavedWindowYLoc = 0;
  205.         TrackObj->SavedWindowWidth = 0;
  206.         TrackObj->SavedWindowHeight = 0;
  207.         return TrackObj;
  208.     }
  209.  
  210.  
  211. /* dispose of track object and all the crud it contains */
  212. void                                    DisposeTrackObject(TrackObjectRec* TrackObj)
  213.     {
  214.         long                                Limit;
  215.         long                                Scan;
  216.  
  217.         CheckPtrExistence(TrackObj);
  218.         if (TrackObj->TrackWindow != NIL)
  219.             {
  220.                 DisposeTrackWindow(TrackObj->TrackWindow);
  221.                 ERROR(TrackObj->TrackWindow != NIL,PRERR(ForceAbort,
  222.                     "DisposeTrackObject:  disposed track window, but window ptr isn't NIL"));
  223.             }
  224.         /* notify dependent views that this object is disappearing */
  225.         Limit = ArrayGetLength(TrackObj->DependentViews);
  226.         for (Scan = 0; Scan < Limit; Scan += 1)
  227.             {
  228.                 TrackViewRec*                ViewObject;
  229.  
  230.                 ViewObject = (TrackViewRec*)ArrayGetElement(TrackObj->DependentViews,Scan);
  231.                 TrackViewObjectTrackDying(ViewObject,TrackObj);
  232.             }
  233.         DisposeArray(TrackObj->DependentViews);
  234.         /* dispose list of background things. have the list dispose all ones */
  235.         /* depending on us. */
  236.         DisposeArray(TrackObj->BackgroundObjects);
  237.         TrackListDelinkBackgroundInstances(TrackObj->TrackList,TrackObj);
  238.         /* dispose notes */
  239.         Limit = ArrayGetLength(TrackObj->FrameArray);
  240.         for (Scan = 0; Scan < Limit; Scan += 1)
  241.             {
  242.                 FrameObjectRec*            Record;
  243.  
  244.                 Record = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,Scan);
  245.                 DisposeFrameAndContents(Record);
  246.             }
  247.         DisposeArray(TrackObj->FrameArray);
  248.         ReleasePtr(TrackObj->InstrumentName);
  249.         ReleasePtr(TrackObj->Name);
  250.         KillMenuItem(TrackObj->TrackMenuItem);
  251.         ReleasePtr(TrackObj->PostProcessingFormula);
  252.         ReleasePtr((char*)TrackObj);
  253.     }
  254.  
  255.  
  256. /* find out if the object has been changed */
  257. MyBoolean                            HasTrackObjectBeenModified(TrackObjectRec* TrackObj)
  258.     {
  259.         CheckPtrExistence(TrackObj);
  260.         /* unlike the other objects, the track object does NOT check the window */
  261.         /* to see if it has been changed because all data is always stored in */
  262.         /* the object itself for tracks */
  263.         return TrackObj->DataModified;
  264.     }
  265.  
  266.  
  267. /* get a copy of the object's name */
  268. char*                                    TrackObjectGetNameCopy(TrackObjectRec* TrackObj)
  269.     {
  270.         char*                                StringTemp;
  271.  
  272.         CheckPtrExistence(TrackObj);
  273.         StringTemp = CopyPtr(TrackObj->Name);
  274.         if (StringTemp != NIL)
  275.             {
  276.                 SetTag(StringTemp,"TrackObjectGetNameCopy");
  277.             }
  278.         return StringTemp;
  279.     }
  280.  
  281.  
  282. /* put a new name.  the object becomes the owner of the name block, so the */
  283. /* caller should not release it */
  284. void                                    TrackObjectPutName(TrackObjectRec* TrackObj, char* Name)
  285.     {
  286.         char*                                NullTerminated;
  287.  
  288.         CheckPtrExistence(TrackObj);
  289.         CheckPtrExistence(Name);
  290.         ReleasePtr(TrackObj->Name);
  291.         TrackObj->Name = Name;
  292.         SetTag(Name,"TrackObjectPutName name");
  293.         TrackObj->DataModified = True; /* no need to call TrackObjectAltered */
  294.         NullTerminated = BlockToStringCopy(Name);
  295.         if (NullTerminated != NIL)
  296.             {
  297.                 if (StrLen(NullTerminated) > 0)
  298.                     {
  299.                         /* it's bad to set menu item names to the empty string! */
  300.                         ChangeItemName(TrackObj->TrackMenuItem,NullTerminated);
  301.                     }
  302.                 ReleasePtr(NullTerminated);
  303.             }
  304.         TrackListTrackNameChanged(TrackObj->TrackList,TrackObj);
  305.     }
  306.  
  307.  
  308. /* get a copy of the name of the instrument that the track will be played with */
  309. char*                                    TrackObjectGetInstrName(TrackObjectRec* TrackObj)
  310.     {
  311.         char*                                StringTemp;
  312.  
  313.         CheckPtrExistence(TrackObj);
  314.         StringTemp = CopyPtr(TrackObj->InstrumentName);
  315.         if (StringTemp != NIL)
  316.             {
  317.                 SetTag(StringTemp,"TrackObjectGetInstrName name");
  318.             }
  319.         return StringTemp;
  320.     }
  321.  
  322.  
  323. /* change the name of the instrument that the track will be played with.  the */
  324. /* track object will become the owner of the block of memory. */
  325. void                                    TrackObjectPutNewInstrName(TrackObjectRec* TrackObj, char* Name)
  326.     {
  327.         CheckPtrExistence(TrackObj);
  328.         CheckPtrExistence(Name);
  329.         ReleasePtr(TrackObj->InstrumentName);
  330.         TrackObj->InstrumentName = Name;
  331.         SetTag(Name,"TrackObjectPutNewInstrName name");
  332.         TrackObj->DataModified = True; /* no need to call TrackObjectAltered */
  333.     }
  334.  
  335.  
  336. /* get a copy of the postprocessing formula */
  337. char*                                    TrackObjectGetPostProcessing(TrackObjectRec* TrackObj)
  338.     {
  339.         char*                                StringTemp;
  340.  
  341.         CheckPtrExistence(TrackObj);
  342.         StringTemp = CopyPtr(TrackObj->PostProcessingFormula);
  343.         if (StringTemp != NIL)
  344.             {
  345.                 SetTag(StringTemp,"PostProcessingFormula");
  346.             }
  347.         return StringTemp;
  348.     }
  349.  
  350.  
  351. /* change the postprocessing formula.  the object becomes owner of the memory block. */
  352. void                                    TrackObjectPutNewPostProcessing(TrackObjectRec* TrackObj,
  353.                                                 char* PostProcExpr)
  354.     {
  355.         CheckPtrExistence(TrackObj);
  356.         CheckPtrExistence(PostProcExpr);
  357.         ReleasePtr(TrackObj->PostProcessingFormula);
  358.         TrackObj->PostProcessingFormula = PostProcExpr;
  359.         SetTag(PostProcExpr,"PostProcessingFormula");
  360.         TrackObj->DataModified = True; /* no need to call TrackObjectAltered */
  361.     }
  362.  
  363.  
  364. /* get number of frames in track */
  365. long                                    TrackObjectGetNumFrames(TrackObjectRec* TrackObj)
  366.     {
  367.         CheckPtrExistence(TrackObj);
  368.         return ArrayGetLength(TrackObj->FrameArray);
  369.     }
  370.  
  371.  
  372. /* get the frame for a given track index */
  373. FrameObjectRec*                TrackObjectGetFrame(TrackObjectRec* TrackObj, long Index)
  374.     {
  375.         CheckPtrExistence(TrackObj);
  376.         ERROR((Index < 0) || (Index >= TrackObjectGetNumFrames(TrackObj)),PRERR(ForceAbort,
  377.             "TrackObjectGetFrame:  index out of range"));
  378.         return (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,Index);
  379.     }
  380.  
  381.  
  382. /* delete a range of frames from the track. */
  383. void                                    TrackObjectDeleteFrameRun(TrackObjectRec* TrackObj,
  384.                                                 long Index, long Count)
  385.     {
  386.         long                                SourceFrameScan;
  387.         long                                SourceFrameLimit;
  388.  
  389.         CheckPtrExistence(TrackObj);
  390.         /* this thing is going to have to be redrawn */
  391.         TrackObjectAltered(TrackObj,Index);
  392.  
  393.         /* do the deletion */
  394.         for (SourceFrameScan = Index; SourceFrameScan < Index + Count; SourceFrameScan += 1)
  395.             {
  396.                 FrameObjectRec*            GallowsFrame;
  397.  
  398.                 GallowsFrame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,Index);
  399.                 ArrayDeleteElement(TrackObj->FrameArray,Index);
  400.                 DisposeFrameAndContents(GallowsFrame);
  401.             }
  402.  
  403.         /* now we have to break any ties that are no longer valid (because their */
  404.         /* targets were just deleted) */
  405.         SourceFrameLimit = ArrayGetLength(TrackObj->FrameArray);
  406.         for (SourceFrameScan = 0; SourceFrameScan < SourceFrameLimit; SourceFrameScan += 1)
  407.             {
  408.                 FrameObjectRec*            SourceFrame;
  409.  
  410.                 SourceFrame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,
  411.                     SourceFrameScan);
  412.                 /* it's either got some notes or one command */
  413.                 if (!IsThisACommandFrame(SourceFrame))
  414.                     {
  415.                         long                                SourceNoteLimit;
  416.                         long                                SourceNoteScan;
  417.  
  418.                         SourceNoteLimit = NumNotesInFrame(SourceFrame);
  419.                         for (SourceNoteScan = 0; SourceNoteScan < SourceNoteLimit;
  420.                             SourceNoteScan += 1)
  421.                             {
  422.                                 NoteObjectRec*            SourceNote;
  423.                                 NoteObjectRec*            TieTarget;
  424.  
  425.                                 SourceNote = GetNoteFromFrame(SourceFrame,SourceNoteScan);
  426.                                 TieTarget = GetNoteTieTarget(SourceNote);
  427.                                 if (TieTarget != NIL)
  428.                                     {
  429.                                         long                                TargetFrameLimit;
  430.                                         long                                TargetFrameScan;
  431.  
  432.                                         TargetFrameLimit = ArrayGetLength(TrackObj->FrameArray);
  433.                                         for (TargetFrameScan = 0; TargetFrameScan < TargetFrameLimit;
  434.                                             TargetFrameScan += 1)
  435.                                             {
  436.                                                 FrameObjectRec*            TargetFrame;
  437.  
  438.                                                 TargetFrame = (FrameObjectRec*)ArrayGetElement(
  439.                                                     TrackObj->FrameArray,TargetFrameScan);
  440.                                                 if (!IsThisACommandFrame(TargetFrame))
  441.                                                     {
  442.                                                         long                                TargetNoteLimit;
  443.                                                         long                                TargetNoteScan;
  444.  
  445.                                                         TargetNoteLimit = NumNotesInFrame(TargetFrame);
  446.                                                         for (TargetNoteScan = 0; TargetNoteScan < TargetNoteLimit;
  447.                                                             TargetNoteScan += 1)
  448.                                                             {
  449.                                                                 if (GetNoteFromFrame(TargetFrame,
  450.                                                                     TargetNoteScan) == TieTarget)
  451.                                                                     {
  452.                                                                         /* tie is valid, so no need to zap it */
  453.                                                                         goto TieValidPoint1;
  454.                                                                     }
  455.                                                             }
  456.                                                     }
  457.                                             } /* end inner frame list scan */
  458.                                         /* the target wasn't found, so we clobber it */
  459.                                         PutNoteTieTarget(SourceNote,NIL);
  460.                                      TieValidPoint1:
  461.                                         ;
  462.                                     }
  463.                             } /* end frame scan */
  464.                     }
  465.             } /* end frame list scan */
  466.     }
  467.  
  468.  
  469. /* get a list of frames and copy them out of the track */
  470. struct ArrayRec*            TrackObjectCopyFrameRun(TrackObjectRec* TrackObj,
  471.                                                 long Index, long Count)
  472.     {
  473.         ArrayRec*                        ReturnList;
  474.         long                                ReturnFrameScan;
  475.         long                                ReturnFrameLimit;
  476.  
  477.         CheckPtrExistence(TrackObj);
  478.  
  479.         /* create the list to hold all of the new things */
  480.         ReturnList = NewArrayReserveSpace(Count);
  481.         if (ReturnList == NIL)
  482.             {
  483.              FailurePoint1:
  484.                 return NIL;
  485.             }
  486.         ReturnFrameScan = Index;
  487.         while (ReturnFrameScan < Index + Count)
  488.             {
  489.                 FrameObjectRec*            OriginalFrame;
  490.                 FrameObjectRec*            DuplicateFrame;
  491.  
  492.                 OriginalFrame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,
  493.                     ReturnFrameScan);
  494.                 DuplicateFrame = DeepDuplicateFrame(OriginalFrame);
  495.                 if (DuplicateFrame == NIL)
  496.                     {
  497.                      FailurePoint2:
  498.                         ReturnFrameLimit = ArrayGetLength(ReturnList);
  499.                         for (ReturnFrameScan = 0; ReturnFrameScan < ReturnFrameLimit;
  500.                             ReturnFrameScan += 1)
  501.                             {
  502.                                 DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(ReturnList,
  503.                                     ReturnFrameScan));
  504.                             }
  505.                         DisposeArray(ReturnList);
  506.                         goto FailurePoint1;
  507.                     }
  508.                 if (!ArrayAppendElement(ReturnList,DuplicateFrame))
  509.                     {
  510.                      FailurePoint2a:
  511.                         DisposeFrameAndContents(DuplicateFrame);
  512.                         goto FailurePoint2;
  513.                     }
  514.                 ReturnFrameScan += 1;
  515.             }
  516.  
  517.         /* now we have to patch up ties.  for each tie in the new array, find the */
  518.         /* note in the old array.  if it corresponds to a note we copied to the new */
  519.         /* array, then fix it up, otherwise set it to NIL. */
  520.         ReturnFrameLimit = ArrayGetLength(ReturnList);
  521.         for (ReturnFrameScan = 0; ReturnFrameScan < ReturnFrameLimit; ReturnFrameScan += 1)
  522.             {
  523.                 FrameObjectRec*            Frame;
  524.  
  525.                 Frame = (FrameObjectRec*)ArrayGetElement(ReturnList,ReturnFrameScan);
  526.                 /* it's either got some notes or one command */
  527.                 if (!IsThisACommandFrame(Frame))
  528.                     {
  529.                         long                                ReturnNoteLimit;
  530.                         long                                ReturnNoteScan;
  531.  
  532.                         ReturnNoteLimit = NumNotesInFrame(Frame);
  533.                         for (ReturnNoteScan = 0; ReturnNoteScan < ReturnNoteLimit;
  534.                             ReturnNoteScan += 1)
  535.                             {
  536.                                 NoteObjectRec*            Note;
  537.                                 NoteObjectRec*            OurNoteTieTarget;
  538.  
  539.                                 Note = GetNoteFromFrame(Frame,ReturnNoteScan);
  540.                                 OurNoteTieTarget = GetNoteTieTarget(Note);
  541.                                 if (OurNoteTieTarget != NIL)
  542.                                     {
  543.                                         long                                OriginalFrameLimit;
  544.                                         long                                OriginalFrameScan;
  545.  
  546.                                         OriginalFrameLimit = ArrayGetLength(TrackObj->FrameArray);
  547.                                         for (OriginalFrameScan = 0; OriginalFrameScan < OriginalFrameLimit;
  548.                                             OriginalFrameScan += 1)
  549.                                             {
  550.                                                 FrameObjectRec*            OrigFrame;
  551.  
  552.                                                 OrigFrame = (FrameObjectRec*)ArrayGetElement(
  553.                                                     TrackObj->FrameArray,OriginalFrameScan);
  554.                                                 if (!IsThisACommandFrame(OrigFrame))
  555.                                                     {
  556.                                                         long                                OriginalNoteLimit;
  557.                                                         long                                OriginalNoteScan;
  558.  
  559.                                                         OriginalNoteLimit = NumNotesInFrame(OrigFrame);
  560.                                                         for (OriginalNoteScan = 0; OriginalNoteScan
  561.                                                             < OriginalNoteLimit; OriginalNoteScan += 1)
  562.                                                             {
  563.                                                                 NoteObjectRec*            Possibility;
  564.  
  565.                                                                 Possibility = GetNoteFromFrame(OrigFrame,
  566.                                                                     OriginalNoteScan);
  567.                                                                 if (Possibility == OurNoteTieTarget)
  568.                                                                     {
  569.                                                                         /* found the tie target */
  570.                                                                         if ((OriginalFrameScan >= Index)
  571.                                                                             && (OriginalFrameScan < Index + Count))
  572.                                                                             {
  573.                                                                                 /* it's a valid tie, so fix it up */
  574.                                                                                 PutNoteTieTarget(Note,GetNoteFromFrame(
  575.                                                                                     (FrameObjectRec*)ArrayGetElement(ReturnList,
  576.                                                                                     OriginalFrameScan - Index),OriginalNoteScan));
  577.                                                                             }
  578.                                                                          else
  579.                                                                             {
  580.                                                                                 /* it isn't valid, so kill it */
  581.                                                                                 PutNoteTieTarget(Note,NIL);
  582.                                                                             }
  583.                                                                         goto TieValidPoint1;
  584.                                                                     }
  585.                                                             }
  586.                                                     }
  587.                                             } /* end inner frame list scan */
  588.                                         EXECUTE(PRERR(ForceAbort,
  589.                                             "TrackObjectCopyFrameRun:  tie target not found"));
  590.                                      TieValidPoint1:
  591.                                         ;
  592.                                     }
  593.                             } /* end frame scan */
  594.                     }
  595.             } /* end frame list scan */
  596.  
  597.         return ReturnList;
  598.     }
  599.  
  600.  
  601. /* find any notes that are referencing the specified note via a tie and nullify the tie. */
  602. void                                    TrackObjectNullifyTies(TrackObjectRec* TrackObj,
  603.                                                 struct NoteObjectRec* NoteThatIsDying)
  604.     {
  605.         long                                FrameScan;
  606.         long                                FrameLimit;
  607.  
  608.         CheckPtrExistence(TrackObj);
  609.         CheckPtrExistence(NoteThatIsDying);
  610.         FrameLimit = ArrayGetLength(TrackObj->FrameArray);
  611.         for (FrameScan = 0; FrameScan < FrameLimit; FrameScan += 1)
  612.             {
  613.                 FrameObjectRec*            Frame;
  614.                 long                                NoteScan;
  615.                 long                                NoteLimit;
  616.  
  617.                 Frame = (FrameObjectRec*)ArrayGetElement(TrackObj->FrameArray,FrameScan);
  618.                 CheckPtrExistence(Frame);
  619.                 NoteLimit = NumNotesInFrame(Frame);
  620.                 for (NoteScan = 0; NoteScan < NoteLimit; NoteScan += 1)
  621.                     {
  622.                         NoteObjectRec*            Note;
  623.  
  624.                         Note = GetNoteFromFrame(Frame,NoteScan);
  625.                         if (!IsItACommand(Note))
  626.                             {
  627.                                 if (GetNoteTieTarget(Note) == NoteThatIsDying)
  628.                                     {
  629.                                         PutNoteTieTarget(Note,NIL);
  630.                                     }
  631.                             }
  632.                     }
  633.             }
  634.         TrackObj->DataModified = True;
  635.     }
  636.  
  637.  
  638. /* insert a frame at the specified position */
  639. MyBoolean                            TrackObjectInsertFrame(TrackObjectRec* TrackObj, long Index,
  640.                                                 struct FrameObjectRec* NewFrame)
  641.     {
  642.         CheckPtrExistence(TrackObj);
  643.         CheckPtrExistence(NewFrame);
  644.         ERROR((Index < 0) || (Index > TrackObjectGetNumFrames(TrackObj)),PRERR(ForceAbort,
  645.             "TrackObjectInsertFrame:  index out of range"));
  646.         if (ArrayInsertElement(TrackObj->FrameArray,NewFrame,Index))
  647.             {
  648.                 TrackObjectAltered(TrackObj,Index);
  649.                 return True;
  650.             }
  651.          else
  652.             {
  653.                 return False;
  654.             }
  655.     }
  656.  
  657.  
  658. /* show the window for this object.  returns True if successful */
  659. MyBoolean                            TrackObjectOpenWindow(TrackObjectRec* TrackObj)
  660.     {
  661.         CheckPtrExistence(TrackObj);
  662.         if (TrackObj->TrackWindow != NIL)
  663.             {
  664.                 TrackWindowBringToTop(TrackObj->TrackWindow);
  665.             }
  666.          else
  667.             {
  668.                 TrackObj->TrackWindow = NewTrackWindow(TrackObj,TrackObj->MainWindow,
  669.                     TrackObj->TrackList,TrackObj->SavedWindowXLoc,TrackObj->SavedWindowYLoc,
  670.                     TrackObj->SavedWindowWidth,TrackObj->SavedWindowHeight);
  671.             }
  672.         return (TrackObj->TrackWindow != NIL);
  673.     }
  674.  
  675.  
  676. /* notify the object that it's window is closing.  the object should take no action */
  677. void                                    TrackObjectClosingWindowNotify(TrackObjectRec* TrackObj,
  678.                                                 short NewX, short NewY, short NewWidth, short NewHeight)
  679.     {
  680.         CheckPtrExistence(TrackObj);
  681.         ERROR(TrackObj->TrackWindow == NIL,PRERR(ForceAbort,
  682.             "TrackObjectClosingWindowNotify:  no window is open"));
  683.         TrackObj->TrackWindow = NIL;
  684.         TrackObj->SavedWindowXLoc = NewX;
  685.         TrackObj->SavedWindowYLoc = NewY;
  686.         TrackObj->SavedWindowWidth = NewWidth;
  687.         TrackObj->SavedWindowHeight = NewHeight;
  688.     }
  689.  
  690.  
  691. /* indicate that the track has been altered starting at a certain position */
  692. /* this sends a message to all track views that have been registered. */
  693. void                                    TrackObjectAltered(TrackObjectRec* TrackObj, long Index)
  694.     {
  695.         long                                Scan;
  696.         long                                Limit;
  697.  
  698.         CheckPtrExistence(TrackObj);
  699.         ERROR((Index < 0) || (Index > TrackObjectGetNumFrames(TrackObj)),PRERR(ForceAbort,
  700.             "TrackObjectAltered:  index out of range"));
  701.         TrackObj->DataModified = True;
  702.         Limit = ArrayGetLength(TrackObj->DependentViews);
  703.         for (Scan = 0; Scan < Limit; Scan += 1)
  704.             {
  705.                 TrackViewRec*                View;
  706.  
  707.                 View = (TrackViewRec*)ArrayGetElement(TrackObj->DependentViews,Scan);
  708.                 TrackViewTrackObjectModified(View,TrackObj,Index);
  709.             }
  710.     }
  711.  
  712.  
  713. /* add a track view object to the list of things that want to be notified when */
  714. /* data in this track is altered */
  715. MyBoolean                            TrackObjectAddDependentView(TrackObjectRec* TrackObj,
  716.                                                 struct TrackViewRec* TheView)
  717.     {
  718.         CheckPtrExistence(TrackObj);
  719.         CheckPtrExistence(TheView);
  720.         ERROR(ArrayFindElement(TrackObj->DependentViews,TheView) >= 0,PRERR(ForceAbort,
  721.             "TrackObjectAddDependentView:  view already on list"));
  722.         return ArrayAppendElement(TrackObj->DependentViews,TheView);
  723.     }
  724.  
  725.  
  726. /* remove a track view object that no longer wants to be notified upon changes */
  727. void                                    TrackObjectRemoveDependentView(TrackObjectRec* TrackObj,
  728.                                                 struct TrackViewRec* TheView)
  729.     {
  730.         CheckPtrExistence(TrackObj);
  731.         ERROR(ArrayFindElement(TrackObj->DependentViews,TheView) < 0,PRERR(ForceAbort,
  732.             "TrackObjectRemoveDependentView:  view isn't in list"));
  733.         ArrayDeleteElement(TrackObj->DependentViews,
  734.             ArrayFindElement(TrackObj->DependentViews,TheView));
  735.     }
  736.  
  737.  
  738. /* add a track view that wants to be seen in the background of this one. */
  739. /* this doesn't actually do too much, since we only keep the list, we don't */
  740. /* do any of the stuff required to actually show it in the background. */
  741. MyBoolean                            TrackObjectAddBackgroundObj(TrackObjectRec* TrackObj,
  742.                                                 TrackObjectRec* OtherTrackObj)
  743.     {
  744.         CheckPtrExistence(TrackObj);
  745.         CheckPtrExistence(OtherTrackObj);
  746.         ERROR(OtherTrackObj == TrackObj,PRERR(ForceAbort,
  747.             "TrackObjectAddBackgroundObj:  adding self to list"));
  748.         ERROR(ArrayFindElement(TrackObj->BackgroundObjects,OtherTrackObj) >= 0,
  749.             PRERR(ForceAbort,"TrackObjectAddBackgroundObj:  view already on list"));
  750.         return ArrayAppendElement(TrackObj->BackgroundObjects,OtherTrackObj);
  751.     }
  752.  
  753.  
  754. /* remove a track view that no longer wants to be seen in the background of this one */
  755. /* the list should call this on everyone when one is deleted so that there aren't */
  756. /* any dangling dependencies left around.  it is not an error to delete something */
  757. /* that isn't in the list */
  758. /* this doesn't actually do too much, since we only keep the list, we don't */
  759. /* do any of the stuff required to actually show it in the background. */
  760. void                                    TrackObjectRemoveBackgroundObj(TrackObjectRec* TrackObj,
  761.                                                 TrackObjectRec* OtherTrackObj)
  762.     {
  763.         long                                Position;
  764.  
  765.         CheckPtrExistence(TrackObj);
  766.         CheckPtrExistence(OtherTrackObj);
  767.         Position = ArrayFindElement(TrackObj->BackgroundObjects,OtherTrackObj);
  768.         if (Position >= 0)
  769.             {
  770.                 ArrayDeleteElement(TrackObj->BackgroundObjects,Position);
  771.             }
  772.     }
  773.  
  774.  
  775. /* get background object list.  (Actual thing). List of TrackObjectRec*'s */
  776. struct ArrayRec*            TrackObjectGetBackgroundList(TrackObjectRec* TrackObj)
  777.     {
  778.         CheckPtrExistence(TrackObj);
  779.         return TrackObj->BackgroundObjects;
  780.     }
  781.  
  782.  
  783. /* get the menu item associated with this track */
  784. struct MenuItemType*    TrackObjectGetMenuItem(TrackObjectRec* TrackObj)
  785.     {
  786.         CheckPtrExistence(TrackObj);
  787.         return TrackObj->TrackMenuItem;
  788.     }
  789.  
  790.  
  791. /* the document's name changed, so we need to update the window */
  792. void                                    TrackObjectGlobalNameChange(TrackObjectRec* TrackObj,
  793.                                                 char* NewFilename)
  794.     {
  795.         CheckPtrExistence(TrackObj);
  796.         if (TrackObj->TrackWindow != NIL)
  797.             {
  798.                 TrackWindowGlobalNameChange(TrackObj->TrackWindow,NewFilename);
  799.             }
  800.     }
  801.  
  802.  
  803. /* get the default early/late hit adjustment factor */
  804. double                                TrackObjectGetEarlyLateAdjust(TrackObjectRec* TrackObj)
  805.     {
  806.         CheckPtrExistence(TrackObj);
  807.         return TrackObj->DefaultEarlyLateAdjust;
  808.     }
  809.  
  810.  
  811. /* get the default first release point */
  812. double                                TrackObjectGetReleasePoint1(TrackObjectRec* TrackObj)
  813.     {
  814.         CheckPtrExistence(TrackObj);
  815.         return TrackObj->DefaultReleasePoint1;
  816.     }
  817.  
  818.  
  819. /* get the default first release point's from start or end flag (this is the same */
  820. /* as the mask used in each note) */
  821. unsigned long                    TrackObjectGetReleasePoint1StartEndFlag(TrackObjectRec* TrackObj)
  822.     {
  823.         CheckPtrExistence(TrackObj);
  824.         return TrackObj->DefaultReleasePoint1ModeFlag;
  825.     }
  826.  
  827.  
  828. /* get the default second release point */
  829. double                                TrackObjectGetReleasePoint2(TrackObjectRec* TrackObj)
  830.     {
  831.         CheckPtrExistence(TrackObj);
  832.         return TrackObj->DefaultReleasePoint2;
  833.     }
  834.  
  835.  
  836. /* get the default second release point's from start or end flag */
  837. unsigned long                    TrackObjectGetReleasePoint2StartEndFlag(TrackObjectRec* TrackObj)
  838.     {
  839.         CheckPtrExistence(TrackObj);
  840.         return TrackObj->DefaultReleasePoint2ModeFlag;
  841.     }
  842.  
  843.  
  844. /* get the default overall loudness adjustment factor */
  845. double                                TrackObjectGetOverallLoudness(TrackObjectRec* TrackObj)
  846.     {
  847.         CheckPtrExistence(TrackObj);
  848.         return TrackObj->DefaultOverallLoudness;
  849.     }
  850.  
  851.  
  852. /* get the default stereo positioning */
  853. double                                TrackObjectGetStereoPositioning(TrackObjectRec* TrackObj)
  854.     {
  855.         CheckPtrExistence(TrackObj);
  856.         return TrackObj->DefaultStereoPositioning;
  857.     }
  858.  
  859.  
  860. /* get the default surround positioning */
  861. double                                TrackObjectGetSurroundPositioning(TrackObjectRec* TrackObj)
  862.     {
  863.         CheckPtrExistence(TrackObj);
  864.         return TrackObj->DefaultSurroundPositioning;
  865.     }
  866.  
  867.  
  868. /* get the default first accent adjust */
  869. double                                TrackObjectGetAccent1(TrackObjectRec* TrackObj)
  870.     {
  871.         CheckPtrExistence(TrackObj);
  872.         return TrackObj->DefaultAccent1;
  873.     }
  874.  
  875.  
  876. /* get the default second accent adjust */
  877. double                                TrackObjectGetAccent2(TrackObjectRec* TrackObj)
  878.     {
  879.         CheckPtrExistence(TrackObj);
  880.         return TrackObj->DefaultAccent2;
  881.     }
  882.  
  883.  
  884. /* get the default third accent adjust */
  885. double                                TrackObjectGetAccent3(TrackObjectRec* TrackObj)
  886.     {
  887.         CheckPtrExistence(TrackObj);
  888.         return TrackObj->DefaultAccent3;
  889.     }
  890.  
  891.  
  892. /* get the default fourth accent adjust */
  893. double                                TrackObjectGetAccent4(TrackObjectRec* TrackObj)
  894.     {
  895.         CheckPtrExistence(TrackObj);
  896.         return TrackObj->DefaultAccent4;
  897.     }
  898.  
  899.  
  900. /* get the default pitch displacement depth adjust */
  901. double                                TrackObjectGetPitchDisplacementDepthAdjust(TrackObjectRec* TrackObj)
  902.     {
  903.         CheckPtrExistence(TrackObj);
  904.         return TrackObj->DefaultPitchDisplacementDepthAdjust;
  905.     }
  906.  
  907.  
  908. /* get the default pitch displacement depth control flag */
  909. unsigned long                    TrackObjectGetPitchDisplacementDepthControlFlag(
  910.                                                 TrackObjectRec* TrackObj)
  911.     {
  912.         CheckPtrExistence(TrackObj);
  913.         return TrackObj->DefaultPitchDisplacementDepthAdjustModeFlag;
  914.     }
  915.  
  916.  
  917. /* get the default pitch displacement rate adjust */
  918. double                                TrackObjectGetPitchDisplacementRateAdjust(TrackObjectRec* TrackObj)
  919.     {
  920.         CheckPtrExistence(TrackObj);
  921.         return TrackObj->DefaultPitchDisplacementRateAdjust;
  922.     }
  923.  
  924.  
  925. /* get the default pitch displacement start point */
  926. double                                TrackObjectGetPitchDisplacementStartPoint(TrackObjectRec* TrackObj)
  927.     {
  928.         CheckPtrExistence(TrackObj);
  929.         return TrackObj->DefaultPitchDisplacementStartPoint;
  930.     }
  931.  
  932.  
  933. /* get the default pitch displacement start point control flag */
  934. unsigned long                    TrackObjectGetPitchDisplacementFromStartOrEnd(
  935.                                                 TrackObjectRec* TrackObj)
  936.     {
  937.         CheckPtrExistence(TrackObj);
  938.         return TrackObj->DefaultPitchDisplacementStartPointModeFlag;
  939.     }
  940.  
  941.  
  942. /* get the default hurry-up factor */
  943. double                                TrackObjectGetHurryUp(TrackObjectRec* TrackObj)
  944.     {
  945.         CheckPtrExistence(TrackObj);
  946.         return TrackObj->DefaultHurryUpFactor;
  947.     }
  948.  
  949.  
  950. /* get the default detuning */
  951. double                                TrackObjectGetDetune(TrackObjectRec* TrackObj)
  952.     {
  953.         CheckPtrExistence(TrackObj);
  954.         return TrackObj->DefaultDetune;
  955.     }
  956.  
  957.  
  958. /* get the detuning control flag */
  959. unsigned long                    TrackObjectGetDetuneControlFlag(TrackObjectRec* TrackObj)
  960.     {
  961.         CheckPtrExistence(TrackObj);
  962.         return TrackObj->DefaultDetuneModeFlag;
  963.     }
  964.  
  965.  
  966. /* get the default duration adjustment */
  967. double                                TrackObjectGetDurationAdjust(TrackObjectRec* TrackObj)
  968.     {
  969.         CheckPtrExistence(TrackObj);
  970.         return TrackObj->DefaultDuration;
  971.     }
  972.  
  973.  
  974. /* get the default duration adjust mode flag */
  975. unsigned long                    TrackObjectGetDurationModeFlag(TrackObjectRec* TrackObj)
  976.     {
  977.         CheckPtrExistence(TrackObj);
  978.         return TrackObj->DefaultDurationModeFlag;
  979.     }
  980.  
  981.  
  982. /* change the default early/late hit adjustment factor */
  983. void                                    PutTrackObjectEarlyLateAdjust(TrackObjectRec* TrackObj,
  984.                                                 double NewEarlyLateAdjust)
  985.     {
  986.         CheckPtrExistence(TrackObj);
  987.         TrackObj->DefaultEarlyLateAdjust = NewEarlyLateAdjust;
  988.         TrackObj->DataModified = True;
  989.     }
  990.  
  991.  
  992. /* change the default first release point */
  993. void                                    PutTrackObjectReleasePoint1(TrackObjectRec* TrackObj,
  994.                                                 double NewReleasePoint1)
  995.     {
  996.         CheckPtrExistence(TrackObj);
  997.         TrackObj->DefaultReleasePoint1 = NewReleasePoint1;
  998.         TrackObj->DataModified = True;
  999.     }
  1000.  
  1001.  
  1002. /* change the default first release point's from start or end flag */
  1003. void                                    PutTrackObjectReleasePoint1StartEndFlag(TrackObjectRec* TrackObj,
  1004.                                                 unsigned long NewReleasePoint1Flag)
  1005.     {
  1006.         CheckPtrExistence(TrackObj);
  1007.         ERROR((NewReleasePoint1Flag != eRelease1FromStart)
  1008.             && (NewReleasePoint1Flag != eRelease1FromEnd),PRERR(AllowResume,
  1009.             "PutTrackObjectReleasePoint1StartEndFlag:  bad value"));
  1010.         TrackObj->DefaultReleasePoint1ModeFlag = NewReleasePoint1Flag;
  1011.         TrackObj->DataModified = True;
  1012.     }
  1013.  
  1014.  
  1015. /* change the default second release point */
  1016. void                                    PutTrackObjectReleasePoint2(TrackObjectRec* TrackObj,
  1017.                                                 double NewReleasePoint2)
  1018.     {
  1019.         CheckPtrExistence(TrackObj);
  1020.         TrackObj->DefaultReleasePoint2 = NewReleasePoint2;
  1021.         TrackObj->DataModified = True;
  1022.     }
  1023.  
  1024.  
  1025. /* change the default second release point's from start or end flag */
  1026. void                                    PutTrackObjectReleasePoint2StartEndFlag(TrackObjectRec* TrackObj,
  1027.                                                 unsigned long NewReleasePoint2Flag)
  1028.     {
  1029.         CheckPtrExistence(TrackObj);
  1030.         ERROR((NewReleasePoint2Flag != eRelease2FromStart)
  1031.             && (NewReleasePoint2Flag != eRelease2FromEnd),PRERR(AllowResume,
  1032.             "PutTrackObjectReleasePoint2StartEndFlag:  bad value"));
  1033.         TrackObj->DefaultReleasePoint2ModeFlag = NewReleasePoint2Flag;
  1034.         TrackObj->DataModified = True;
  1035.     }
  1036.  
  1037.  
  1038. /* change the default overall loudness adjustment factor */
  1039. void                                    PutTrackObjectOverallLoudness(TrackObjectRec* TrackObj,
  1040.                                                 double NewOverallLoudness)
  1041.     {
  1042.         CheckPtrExistence(TrackObj);
  1043.         TrackObj->DefaultOverallLoudness = NewOverallLoudness;
  1044.         TrackObj->DataModified = True;
  1045.     }
  1046.  
  1047.  
  1048. /* change the default stereo positioning value */
  1049. void                                    PutTrackObjectStereoPositioning(TrackObjectRec* TrackObj,
  1050.                                                 double NewStereoPositioning)
  1051.     {
  1052.         CheckPtrExistence(TrackObj);
  1053.         TrackObj->DefaultStereoPositioning = NewStereoPositioning;
  1054.         TrackObj->DataModified = True;
  1055.     }
  1056.  
  1057.  
  1058. /* change the default surround positioning value */
  1059. void                                    PutTrackObjectSurroundPositioning(TrackObjectRec* TrackObj,
  1060.                                                 double NewSurroundPositioning)
  1061.     {
  1062.         CheckPtrExistence(TrackObj);
  1063.         TrackObj->DefaultSurroundPositioning = NewSurroundPositioning;
  1064.         TrackObj->DataModified = True;
  1065.     }
  1066.  
  1067.  
  1068. /* change the default first accent adjust */
  1069. void                                    PutTrackObjectAccent1(TrackObjectRec* TrackObj,
  1070.                                                 double NewAccent1)
  1071.     {
  1072.         CheckPtrExistence(TrackObj);
  1073.         TrackObj->DefaultAccent1 = NewAccent1;
  1074.         TrackObj->DataModified = True;
  1075.     }
  1076.  
  1077.  
  1078. /* change the default second accent adjust */
  1079. void                                    PutTrackObjectAccent2(TrackObjectRec* TrackObj,
  1080.                                                 double NewAccent2)
  1081.     {
  1082.         CheckPtrExistence(TrackObj);
  1083.         TrackObj->DefaultAccent2 = NewAccent2;
  1084.         TrackObj->DataModified = True;
  1085.     }
  1086.  
  1087.  
  1088. /* change the default third accent adjust */
  1089. void                                    PutTrackObjectAccent3(TrackObjectRec* TrackObj,
  1090.                                                 double NewAccent3)
  1091.     {
  1092.         CheckPtrExistence(TrackObj);
  1093.         TrackObj->DefaultAccent3 = NewAccent3;
  1094.         TrackObj->DataModified = True;
  1095.     }
  1096.  
  1097.  
  1098. /* change the default fourth accent adjust */
  1099. void                                    PutTrackObjectAccent4(TrackObjectRec* TrackObj,
  1100.                                                 double NewAccent4)
  1101.     {
  1102.         CheckPtrExistence(TrackObj);
  1103.         TrackObj->DefaultAccent4 = NewAccent4;
  1104.         TrackObj->DataModified = True;
  1105.     }
  1106.  
  1107.  
  1108. /* change the default pitch displacement depth adjust */
  1109. void                                    PutTrackObjectPitchDisplacementDepthAdjust(TrackObjectRec* TrackObj,
  1110.                                                 double NewPitchDisplacementDepthAdjust)
  1111.     {
  1112.         CheckPtrExistence(TrackObj);
  1113.         TrackObj->DefaultPitchDisplacementDepthAdjust = NewPitchDisplacementDepthAdjust;
  1114.         TrackObj->DataModified = True;
  1115.     }
  1116.  
  1117.  
  1118. /* change the default pitch displacement depth control flag */
  1119. void                                    PutTrackObjectPitchDisplacementDepthControlFlag(TrackObjectRec*
  1120.                                                 TrackObj, unsigned long NewPitchDisplacementDepthControlFlag)
  1121.     {
  1122.         CheckPtrExistence(TrackObj);
  1123.         ERROR((NewPitchDisplacementDepthControlFlag != ePitchDisplacementDepthModeHalfSteps)
  1124.             && (NewPitchDisplacementDepthControlFlag != ePitchDisplacementDepthModeHertz),
  1125.             PRERR(AllowResume,"PutTrackObjectPitchDisplacementDepthControlFlag:  bad value"));
  1126.         TrackObj->DefaultPitchDisplacementDepthAdjustModeFlag
  1127.             = NewPitchDisplacementDepthControlFlag;
  1128.         TrackObj->DataModified = True;
  1129.     }
  1130.  
  1131.  
  1132. /* change the default pitch displacement rate adjust */
  1133. void                                    PutTrackObjectPitchDisplacementRateAdjust(TrackObjectRec* TrackObj,
  1134.                                                 double NewPitchDisplacementRate)
  1135.     {
  1136.         CheckPtrExistence(TrackObj);
  1137.         TrackObj->DefaultPitchDisplacementRateAdjust = NewPitchDisplacementRate;
  1138.         TrackObj->DataModified = True;
  1139.     }
  1140.  
  1141.  
  1142. /* change the default pitch displacement start point */
  1143. void                                    PutTrackObjectPitchDisplacementStartPoint(TrackObjectRec* TrackObj,
  1144.                                                 double NewPitchDisplacementStartPoint)
  1145.     {
  1146.         CheckPtrExistence(TrackObj);
  1147.         TrackObj->DefaultPitchDisplacementStartPoint = NewPitchDisplacementStartPoint;
  1148.         TrackObj->DataModified = True;
  1149.     }
  1150.  
  1151.  
  1152. /* change the default pitch displacement start point control flag */
  1153. void                                    PutTrackObjectPitchDisplacementFromStartOrEnd(TrackObjectRec*
  1154.                                                 TrackObj, unsigned long NewPitchDisplacementStartPointControl)
  1155.     {
  1156.         CheckPtrExistence(TrackObj);
  1157.         ERROR((NewPitchDisplacementStartPointControl != ePitchDisplacementStartFromStart)
  1158.             && (NewPitchDisplacementStartPointControl != ePitchDisplacementStartFromEnd),
  1159.             PRERR(AllowResume,"PutTrackObjectPitchDisplacementFromStartOrEnd:  bad value"));
  1160.         TrackObj->DefaultPitchDisplacementStartPointModeFlag
  1161.             = NewPitchDisplacementStartPointControl;
  1162.         TrackObj->DataModified = True;
  1163.     }
  1164.  
  1165.  
  1166. /* change the default hurry-up factor */
  1167. void                                    PutTrackObjectHurryUp(TrackObjectRec* TrackObj, double NewHurryUp)
  1168.     {
  1169.         CheckPtrExistence(TrackObj);
  1170.         TrackObj->DefaultHurryUpFactor = NewHurryUp;
  1171.         TrackObj->DataModified = True;
  1172.     }
  1173.  
  1174.  
  1175. /* change the default detuning */
  1176. void                                    PutTrackObjectDetune(TrackObjectRec* TrackObj, double NewDetune)
  1177.     {
  1178.         CheckPtrExistence(TrackObj);
  1179.         TrackObj->DefaultDetune = NewDetune;
  1180.         TrackObj->DataModified = True;
  1181.     }
  1182.  
  1183.  
  1184. /* change the detuning control flag */
  1185. void                                    PutTrackObjectDetuneControlFlag(TrackObjectRec* TrackObj,
  1186.                                                 unsigned long NewDetuneControlFlag)
  1187.     {
  1188.         CheckPtrExistence(TrackObj);
  1189.         ERROR((NewDetuneControlFlag != eDetuningModeHalfSteps)
  1190.             && (NewDetuneControlFlag != eDetuningModeHertz),PRERR(AllowResume,
  1191.             "PutTrackObjectDetuneControlFlag:  bad value"));
  1192.         TrackObj->DefaultDetuneModeFlag = NewDetuneControlFlag;
  1193.         TrackObj->DataModified = True;
  1194.     }
  1195.  
  1196.  
  1197. /* change the default duration adjustment */
  1198. void                                    PutTrackObjectDurationAdjust(TrackObjectRec* TrackObj,
  1199.                                                 double NewDurationAdjust)
  1200.     {
  1201.         CheckPtrExistence(TrackObj);
  1202.         TrackObj->DefaultDuration = NewDurationAdjust;
  1203.         TrackObj->DataModified = True;
  1204.     }
  1205.  
  1206.  
  1207. /* change the default duration adjust mode flag */
  1208. void                                    PutTrackObjectDurationModeFlag(TrackObjectRec* TrackObj,
  1209.                                                 unsigned long NewDurationModeFlag)
  1210.     {
  1211.         CheckPtrExistence(TrackObj);
  1212.         ERROR((NewDurationModeFlag != eDurationAdjustAdditive)
  1213.             && (NewDurationModeFlag != eDurationAdjustMultiplicative),PRERR(AllowResume,
  1214.             "PutTrackObjectDurationModeFlag:  bad value"));
  1215.         TrackObj->DefaultDurationModeFlag = NewDurationModeFlag;
  1216.         TrackObj->DataModified = True;
  1217.     }
  1218.  
  1219.  
  1220. /* find out if this track should be included when we play the score */
  1221. MyBoolean                            TrackObjectShouldItBePlayed(TrackObjectRec* TrackObj)
  1222.     {
  1223.         CheckPtrExistence(TrackObj);
  1224.         return TrackObj->IncludeThisTrackInFinalPlayback;
  1225.     }
  1226.  
  1227.  
  1228. /* chage status of whether track should be played */
  1229. void                                    ChangeTrackObjectShouldBePlayed(TrackObjectRec* TrackObj,
  1230.                                                 MyBoolean ShouldWePlayIt)
  1231.     {
  1232.         CheckPtrExistence(TrackObj);
  1233.         TrackObj->IncludeThisTrackInFinalPlayback = ShouldWePlayIt;
  1234.         /* don't set DataModified */
  1235.     }
  1236.  
  1237.  
  1238. /* Track Object Subblock Format: */
  1239. /*   1-byte format version number */
  1240. /*       should be 1 */
  1241. /*   2-byte little endian window X position (signed; from top-left corner of screen) */
  1242. /*   2-byte little endian window Y position */
  1243. /*   2-byte little endian window width */
  1244. /*   2-byte little endian window height */
  1245. /*   4-byte little endian track name length descriptor */
  1246. /*   n-byte track name string (line feed = 0x0a) */
  1247. /*   4-byte little endian large integer coded decimal default early/late adjust */
  1248. /*       large integer coded decimal is decimal * 1000000 with a */
  1249. /*       range of -1999.999999 to 1999.999999 */
  1250. /*   4-byte little endian large integer coded decimal default release point 1 */
  1251. /*   1-byte default release point 1 mode flag */
  1252. /*       0 = release from start */
  1253. /*       1 = release from end */
  1254. /*   4-byte little endian large integer coded decimal default release point 2 */
  1255. /*   1-byte default release point 2 mode flag */
  1256. /*       0 = release from start */
  1257. /*       1 = release from end */
  1258. /*   4-byte little endian large integer coded decimal default overall loudness */
  1259. /*   4-byte little endian large integer coded decimal default stereo positioning */
  1260. /*   4-byte little endian large integer coded decimal default surround positioning */
  1261. /*   4-byte little endian large integer coded decimal default accent 1 */
  1262. /*   4-byte little endian large integer coded decimal default accent 2 */
  1263. /*   4-byte little endian large integer coded decimal default accent 3 */
  1264. /*   4-byte little endian large integer coded decimal default accent 4 */
  1265. /*   4-byte little endian large integer coded decimal default pitch disp depth adjust */
  1266. /*   1-byte default pitch displacement depth adjust mode flag */
  1267. /*       0 = half steps */
  1268. /*       1 = hertz */
  1269. /*   4-byte little endian large integer coded decimal default pitch disp rate adjust */
  1270. /*   4-byte little endian large integer coded decimal default pitch disp start point */
  1271. /*   1-byte default pitch displacement start point mode flag */
  1272. /*       0 = pitch displacement point from start */
  1273. /*       1 = pitch displacement point from end */
  1274. /*   4-byte little endian large integer coded decimal default hurry-up factor */
  1275. /*   4-byte little endian large integer coded decimal default detuning */
  1276. /*   1-byte default detuning mode flag */
  1277. /*       0 = half steps */
  1278. /*       1 = hertz */
  1279. /*   4-byte little endian large integer coded decimal default duration */
  1280. /*   1-byte default duration mode flag */
  1281. /*       0 = duration adjust is multiplicative */
  1282. /*       1 = duration adjust is additive */
  1283. /*   1-byte flag for playback inclusion */
  1284. /*       0 = don't play track in final playback */
  1285. /*       1 = do play track in final playback */
  1286. /*   4-byte little endian instrument name string length descriptor */
  1287. /*   n-byte instrument name string (line feed = 0x0a) */
  1288. /*   1-byte flag for channel post processing enabling */
  1289. /*       0 = don't do channel postprocessing */
  1290. /*       1 = do channel postprocessing */
  1291. /*   4-byte little endian postprocessing expression length descriptor */
  1292. /*   n-bytes of postprocessing stuff (line feed = 0x0a) */
  1293. /*   n-bytes of data for note vector */
  1294.  
  1295.  
  1296. /* read track information from the file and create a new track object */
  1297. FileLoadingErrors            TrackObjectNewFromFile(TrackObjectRec** ObjectOut,
  1298.                                                 struct BufferedInputRec* Input, struct CodeCenterRec* CodeCenter,
  1299.                                                 struct MainWindowRec* MainWindow, struct TrackListRec* TrackList)
  1300.     {
  1301.         TrackObjectRec*            TrackObj;
  1302.         FileLoadingErrors        Error;
  1303.         unsigned char                UnsignedChar;
  1304.         signed short                SignedShort;
  1305.         signed long                    SignedLong;
  1306.         char*                                NullTerminated;
  1307.  
  1308.         CheckPtrExistence(Input);
  1309.         CheckPtrExistence(CodeCenter);
  1310.         CheckPtrExistence(MainWindow);
  1311.         CheckPtrExistence(TrackList);
  1312.  
  1313.         TrackObj = (TrackObjectRec*)AllocPtrCanFail(sizeof(TrackObjectRec),"TrackObjectRec");
  1314.         if (TrackObj == NIL)
  1315.             {
  1316.                 Error = eFileLoadOutOfMemory;
  1317.              FailurePoint1:
  1318.                 return Error;
  1319.             }
  1320.  
  1321.         /*   1-byte format version number */
  1322.         /*       should be 1 */
  1323.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1324.             {
  1325.                 Error = eFileLoadDiskError;
  1326.              FailurePoint2:
  1327.                 ReleasePtr((char*)TrackObj);
  1328.                 goto FailurePoint1;
  1329.             }
  1330.         if (UnsignedChar != 1)
  1331.             {
  1332.                 Error = eFileLoadBadFormat;
  1333.              FailurePoint3:
  1334.                 goto FailurePoint2;
  1335.             }
  1336.  
  1337.         /*   2-byte little endian window X position (signed; from top-left corner of screen) */
  1338.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1339.             {
  1340.                 Error = eFileLoadDiskError;
  1341.              FailurePoint4:
  1342.                 goto FailurePoint3;
  1343.             }
  1344.         TrackObj->SavedWindowXLoc = SignedShort;
  1345.  
  1346.         /*   2-byte little endian window Y position */
  1347.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1348.             {
  1349.                 Error = eFileLoadDiskError;
  1350.              FailurePoint5:
  1351.                 goto FailurePoint4;
  1352.             }
  1353.         TrackObj->SavedWindowYLoc = SignedShort;
  1354.  
  1355.         /*   2-byte little endian window width */
  1356.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1357.             {
  1358.                 Error = eFileLoadDiskError;
  1359.              FailurePoint6:
  1360.                 goto FailurePoint5;
  1361.             }
  1362.         TrackObj->SavedWindowWidth = SignedShort;
  1363.  
  1364.         /*   2-byte little endian window height */
  1365.         if (!ReadBufferedSignedShortLittleEndian(Input,&SignedShort))
  1366.             {
  1367.                 Error = eFileLoadDiskError;
  1368.              FailurePoint7:
  1369.                 goto FailurePoint6;
  1370.             }
  1371.         TrackObj->SavedWindowHeight = SignedShort;
  1372.  
  1373.         /*   4-byte little endian track name length descriptor */
  1374.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1375.             {
  1376.                 Error = eFileLoadDiskError;
  1377.              FailurePoint8:
  1378.                 goto FailurePoint7;
  1379.             }
  1380.         if (SignedLong < 0)
  1381.             {
  1382.                 Error = eFileLoadBadFormat;
  1383.              FailurePoint9:
  1384.                 goto FailurePoint8;
  1385.             }
  1386.  
  1387.         /*   n-byte track name string (line feed = 0x0a) */
  1388.         TrackObj->Name = AllocPtrCanFail(SignedLong,"TrackObjectRec:  name");
  1389.         if (TrackObj->Name == NIL)
  1390.             {
  1391.                 Error = eFileLoadOutOfMemory;
  1392.              FailurePoint10:
  1393.                 goto FailurePoint9;
  1394.             }
  1395.         if (!ReadBufferedInput(Input,SignedLong,TrackObj->Name))
  1396.             {
  1397.                 Error = eFileLoadDiskError;
  1398.              FailurePoint11:
  1399.                 ReleasePtr(TrackObj->Name);
  1400.                 goto FailurePoint10;
  1401.             }
  1402.  
  1403.         /*   4-byte little endian large integer coded decimal default early/late adjust */
  1404.         /*       large integer coded decimal is decimal * 1000000 with a */
  1405.         /*       range of -1999.999999 to 1999.999999 */
  1406.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1407.             {
  1408.                 Error = eFileLoadDiskError;
  1409.              FailurePoint12:
  1410.                 goto FailurePoint11;
  1411.             }
  1412.         TrackObj->DefaultEarlyLateAdjust = LargeBCD2Double(SignedLong);
  1413.  
  1414.         /*   4-byte little endian large integer coded decimal default release point 1 */
  1415.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1416.             {
  1417.                 Error = eFileLoadDiskError;
  1418.              FailurePoint13:
  1419.                 goto FailurePoint12;
  1420.             }
  1421.         TrackObj->DefaultReleasePoint1 = LargeBCD2Double(SignedLong);
  1422.  
  1423.         /*   1-byte default release point 1 mode flag */
  1424.         /*       0 = release from start */
  1425.         /*       1 = release from end */
  1426.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1427.             {
  1428.                 Error = eFileLoadDiskError;
  1429.              FailurePoint14:
  1430.                 goto FailurePoint13;
  1431.             }
  1432.         if (UnsignedChar == 0)
  1433.             {
  1434.                 TrackObj->DefaultReleasePoint1ModeFlag = eRelease1FromStart;
  1435.             }
  1436.         else if (UnsignedChar == 1)
  1437.             {
  1438.                 TrackObj->DefaultReleasePoint1ModeFlag = eRelease1FromEnd;
  1439.             }
  1440.         else
  1441.             {
  1442.                 Error = eFileLoadBadFormat;
  1443.              FailurePoint15:
  1444.                 goto FailurePoint14;
  1445.             }
  1446.  
  1447.         /*   4-byte little endian large integer coded decimal default release point 2 */
  1448.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1449.             {
  1450.                 Error = eFileLoadDiskError;
  1451.              FailurePoint16:
  1452.                 goto FailurePoint15;
  1453.             }
  1454.         TrackObj->DefaultReleasePoint2 = LargeBCD2Double(SignedLong);
  1455.  
  1456.         /*   1-byte default release point 2 mode flag */
  1457.         /*       0 = release from start */
  1458.         /*       1 = release from end */
  1459.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1460.             {
  1461.                 Error = eFileLoadDiskError;
  1462.              FailurePoint17:
  1463.                 goto FailurePoint16;
  1464.             }
  1465.         if (UnsignedChar == 0)
  1466.             {
  1467.                 TrackObj->DefaultReleasePoint2ModeFlag = eRelease2FromStart;
  1468.             }
  1469.         else if (UnsignedChar == 1)
  1470.             {
  1471.                 TrackObj->DefaultReleasePoint2ModeFlag = eRelease2FromEnd;
  1472.             }
  1473.         else
  1474.             {
  1475.                 Error = eFileLoadBadFormat;
  1476.              FailurePoint18:
  1477.                 goto FailurePoint17;
  1478.             }
  1479.  
  1480.         /*   4-byte little endian large integer coded decimal default overall loudness */
  1481.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1482.             {
  1483.                 Error = eFileLoadDiskError;
  1484.              FailurePoint19:
  1485.                 goto FailurePoint18;
  1486.             }
  1487.         TrackObj->DefaultOverallLoudness = LargeBCD2Double(SignedLong);
  1488.  
  1489.         /*   4-byte little endian large integer coded decimal default stereo positioning */
  1490.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1491.             {
  1492.                 Error = eFileLoadDiskError;
  1493.              FailurePoint20:
  1494.                 goto FailurePoint19;
  1495.             }
  1496.         TrackObj->DefaultStereoPositioning = LargeBCD2Double(SignedLong);
  1497.  
  1498.         /*   4-byte little endian large integer coded decimal default surround positioning */
  1499.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1500.             {
  1501.                 Error = eFileLoadDiskError;
  1502.              FailurePoint20oops:
  1503.                 goto FailurePoint20;
  1504.             }
  1505.         TrackObj->DefaultSurroundPositioning = LargeBCD2Double(SignedLong);
  1506.  
  1507.         /*   4-byte little endian large integer coded decimal default accent 1 */
  1508.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1509.             {
  1510.                 Error = eFileLoadDiskError;
  1511.              FailurePoint21:
  1512.                 goto FailurePoint20oops;
  1513.             }
  1514.         TrackObj->DefaultAccent1 = LargeBCD2Double(SignedLong);
  1515.  
  1516.         /*   4-byte little endian large integer coded decimal default accent 2 */
  1517.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1518.             {
  1519.                 Error = eFileLoadDiskError;
  1520.              FailurePoint22:
  1521.                 goto FailurePoint21;
  1522.             }
  1523.         TrackObj->DefaultAccent2 = LargeBCD2Double(SignedLong);
  1524.  
  1525.         /*   4-byte little endian large integer coded decimal default accent 3 */
  1526.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1527.             {
  1528.                 Error = eFileLoadDiskError;
  1529.              FailurePoint23:
  1530.                 goto FailurePoint22;
  1531.             }
  1532.         TrackObj->DefaultAccent3 = LargeBCD2Double(SignedLong);
  1533.  
  1534.         /*   4-byte little endian large integer coded decimal default accent 4 */
  1535.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1536.             {
  1537.                 Error = eFileLoadDiskError;
  1538.              FailurePoint24:
  1539.                 goto FailurePoint23;
  1540.             }
  1541.         TrackObj->DefaultAccent4 = LargeBCD2Double(SignedLong);
  1542.  
  1543.         /*   4-byte little endian large integer coded decimal default pitch disp depth adjust */
  1544.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1545.             {
  1546.                 Error = eFileLoadDiskError;
  1547.              FailurePoint25:
  1548.                 goto FailurePoint24;
  1549.             }
  1550.         TrackObj->DefaultPitchDisplacementDepthAdjust = LargeBCD2Double(SignedLong);
  1551.  
  1552.         /*   1-byte default pitch displacement depth adjust mode flag */
  1553.         /*       0 = half steps */
  1554.         /*       1 = hertz */
  1555.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1556.             {
  1557.                 Error = eFileLoadDiskError;
  1558.              FailurePoint26:
  1559.                 goto FailurePoint25;
  1560.             }
  1561.         if (UnsignedChar == 0)
  1562.             {
  1563.                 TrackObj->DefaultPitchDisplacementDepthAdjustModeFlag
  1564.                     = ePitchDisplacementDepthModeHalfSteps;
  1565.             }
  1566.         else if (UnsignedChar == 1)
  1567.             {
  1568.                 TrackObj->DefaultPitchDisplacementDepthAdjustModeFlag
  1569.                     = ePitchDisplacementDepthModeHertz;
  1570.             }
  1571.         else
  1572.             {
  1573.                 Error = eFileLoadBadFormat;
  1574.              FailurePoint27:
  1575.                 goto FailurePoint26;
  1576.             }
  1577.  
  1578.         /*   4-byte little endian large integer coded decimal default pitch disp rate adjust */
  1579.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1580.             {
  1581.                 Error = eFileLoadDiskError;
  1582.              FailurePoint28:
  1583.                 goto FailurePoint27;
  1584.             }
  1585.         TrackObj->DefaultPitchDisplacementRateAdjust = LargeBCD2Double(SignedLong);
  1586.  
  1587.         /*   4-byte little endian large integer coded decimal default pitch disp start point */
  1588.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1589.             {
  1590.                 Error = eFileLoadDiskError;
  1591.              FailurePoint29:
  1592.                 goto FailurePoint28;
  1593.             }
  1594.         TrackObj->DefaultPitchDisplacementStartPoint = LargeBCD2Double(SignedLong);
  1595.  
  1596.         /*   1-byte default pitch displacement start point mode flag */
  1597.         /*       0 = pitch displacement point from start */
  1598.         /*       1 = pitch displacement point from end */
  1599.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1600.             {
  1601.                 Error = eFileLoadDiskError;
  1602.              FailurePoint30:
  1603.                 goto FailurePoint29;
  1604.             }
  1605.         if (UnsignedChar == 0)
  1606.             {
  1607.                 TrackObj->DefaultPitchDisplacementStartPointModeFlag
  1608.                     = ePitchDisplacementStartFromStart;
  1609.             }
  1610.         else if (UnsignedChar == 1)
  1611.             {
  1612.                 TrackObj->DefaultPitchDisplacementStartPointModeFlag
  1613.                     = ePitchDisplacementStartFromEnd;
  1614.             }
  1615.         else
  1616.             {
  1617.                 Error = eFileLoadBadFormat;
  1618.              FailurePoint31:
  1619.                 goto FailurePoint30;
  1620.             }
  1621.  
  1622.         /*   4-byte little endian large integer coded decimal default hurry-up factor */
  1623.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1624.             {
  1625.                 Error = eFileLoadDiskError;
  1626.              FailurePoint32:
  1627.                 goto FailurePoint31;
  1628.             }
  1629.         TrackObj->DefaultHurryUpFactor = LargeBCD2Double(SignedLong);
  1630.  
  1631.         /*   4-byte little endian large integer coded decimal default detuning */
  1632.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1633.             {
  1634.                 Error = eFileLoadDiskError;
  1635.              FailurePoint33:
  1636.                 goto FailurePoint32;
  1637.             }
  1638.         TrackObj->DefaultDetune = LargeBCD2Double(SignedLong);
  1639.  
  1640.         /*   1-byte default detuning mode flag */
  1641.         /*       0 = half steps */
  1642.         /*       1 = hertz */
  1643.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1644.             {
  1645.                 Error = eFileLoadDiskError;
  1646.              FailurePoint34:
  1647.                 goto FailurePoint33;
  1648.             }
  1649.         if (UnsignedChar == 0)
  1650.             {
  1651.                 TrackObj->DefaultDetuneModeFlag = eDetuningModeHalfSteps;
  1652.             }
  1653.         else if (UnsignedChar == 1)
  1654.             {
  1655.                 TrackObj->DefaultDetuneModeFlag = eDetuningModeHertz;
  1656.             }
  1657.         else
  1658.             {
  1659.                 Error = eFileLoadBadFormat;
  1660.              FailurePoint35:
  1661.                 goto FailurePoint34;
  1662.             }
  1663.  
  1664.         /*   4-byte little endian large integer coded decimal default duration */
  1665.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1666.             {
  1667.                 Error = eFileLoadDiskError;
  1668.              FailurePoint36:
  1669.                 goto FailurePoint35;
  1670.             }
  1671.         TrackObj->DefaultDuration = LargeBCD2Double(SignedLong);
  1672.  
  1673.         /*   1-byte default duration mode flag */
  1674.         /*       0 = duration adjust is multiplicative */
  1675.         /*       1 = duration adjust is additive */
  1676.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1677.             {
  1678.                 Error = eFileLoadDiskError;
  1679.              FailurePoint37:
  1680.                 goto FailurePoint36;
  1681.             }
  1682.         if (UnsignedChar == 0)
  1683.             {
  1684.                 TrackObj->DefaultDurationModeFlag = eDurationAdjustMultiplicative;
  1685.             }
  1686.         else if (UnsignedChar == 1)
  1687.             {
  1688.                 TrackObj->DefaultDurationModeFlag = eDurationAdjustAdditive;
  1689.             }
  1690.         else
  1691.             {
  1692.                 Error = eFileLoadBadFormat;
  1693.              FailurePoint38:
  1694.                 goto FailurePoint37;
  1695.             }
  1696.  
  1697.         /*   1-byte flag for playback inclusion */
  1698.         /*       0 = don't play track in final playback */
  1699.         /*       1 = do play track in final playback */
  1700.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1701.             {
  1702.                 Error = eFileLoadDiskError;
  1703.              FailurePoint39:
  1704.                 goto FailurePoint38;
  1705.             }
  1706.         if (UnsignedChar == 0)
  1707.             {
  1708.                 TrackObj->IncludeThisTrackInFinalPlayback = False;
  1709.             }
  1710.         else if (UnsignedChar == 1)
  1711.             {
  1712.                 TrackObj->IncludeThisTrackInFinalPlayback = True;
  1713.             }
  1714.         else
  1715.             {
  1716.                 Error = eFileLoadBadFormat;
  1717.              FailurePoint40:
  1718.                 goto FailurePoint39;
  1719.             }
  1720.  
  1721.         /*   4-byte little endian instrument name string length descriptor */
  1722.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1723.             {
  1724.                 Error = eFileLoadDiskError;
  1725.              FailurePoint41:
  1726.                 goto FailurePoint40;
  1727.             }
  1728.         if (SignedLong < 0)
  1729.             {
  1730.                 Error = eFileLoadBadFormat;
  1731.              FailurePoint42:
  1732.                 goto FailurePoint41;
  1733.             }
  1734.  
  1735.         /*   n-byte instrument name string (line feed = 0x0a) */
  1736.         TrackObj->InstrumentName = AllocPtrCanFail(SignedLong,"TrackObjectRec:  instr name");
  1737.         if (TrackObj->InstrumentName == NIL)
  1738.             {
  1739.                 Error = eFileLoadOutOfMemory;
  1740.              FailurePoint43:
  1741.                 goto FailurePoint42;
  1742.             }
  1743.         if (!ReadBufferedInput(Input,SignedLong,TrackObj->InstrumentName))
  1744.             {
  1745.                 Error = eFileLoadDiskError;
  1746.              FailurePoint44:
  1747.                 ReleasePtr(TrackObj->InstrumentName);
  1748.                 goto FailurePoint43;
  1749.             }
  1750.  
  1751.         /*   1-byte flag for channel post processing enabling */
  1752.         /*       0 = don't do channel postprocessing */
  1753.         /*       1 = do channel postprocessing */
  1754.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  1755.             {
  1756.                 Error = eFileLoadDiskError;
  1757.              FailurePoint44a:
  1758.                 goto FailurePoint44;
  1759.             }
  1760.         if (UnsignedChar == 0)
  1761.             {
  1762.                 TrackObj->PostProcessingEnable = False;
  1763.             }
  1764.         else if (UnsignedChar == 1)
  1765.             {
  1766.                 TrackObj->PostProcessingEnable = True;
  1767.             }
  1768.         else
  1769.             {
  1770.                 Error = eFileLoadBadFormat;
  1771.              FailurePoint44b:
  1772.                 goto FailurePoint44a;
  1773.             }
  1774.  
  1775.         /*   4-byte little endian postprocessing expression length descriptor */
  1776.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  1777.             {
  1778.                 Error = eFileLoadDiskError;
  1779.              FailurePoint45:
  1780.                 goto FailurePoint44b;
  1781.             }
  1782.         if (SignedLong < 0)
  1783.             {
  1784.                 Error = eFileLoadBadFormat;
  1785.              FailurePoint46:
  1786.                 goto FailurePoint45;
  1787.             }
  1788.  
  1789.         /*   n-bytes of postprocessing stuff (line feed = 0x0a) */
  1790.         TrackObj->PostProcessingFormula = AllocPtrCanFail(SignedLong,"PostProcessingFormula");
  1791.         if (TrackObj->PostProcessingFormula == NIL)
  1792.             {
  1793.                 Error = eFileLoadOutOfMemory;
  1794.              FailurePoint47:
  1795.                 goto FailurePoint46;
  1796.             }
  1797.         if (!ReadBufferedInput(Input,SignedLong,TrackObj->PostProcessingFormula))
  1798.             {
  1799.                 Error = eFileLoadDiskError;
  1800.              FailurePoint48:
  1801.                 ReleasePtr(TrackObj->PostProcessingFormula);
  1802.                 goto FailurePoint47;
  1803.             }
  1804.  
  1805.         /*   n-bytes of data for note array */
  1806.         EXECUTE(TrackObj->FrameArray = (ArrayRec*)0x81818181;)
  1807.         Error = ReadNoteVector(&(TrackObj->FrameArray),Input);
  1808.         if (Error != eFileLoadNoError)
  1809.             {
  1810.              FailurePoint49:
  1811.                 goto FailurePoint48;
  1812.             }
  1813.         CheckPtrExistence(TrackObj->FrameArray);
  1814.  
  1815.         /* fill in the other fields */
  1816.         TrackObj->DataModified = False;
  1817.         TrackObj->DependentViews = NewArray();
  1818.         if (TrackObj->DependentViews == NIL)
  1819.             {
  1820.                 long                        Scan;
  1821.                 long                        Limit;
  1822.  
  1823.                 Error = eFileLoadOutOfMemory;
  1824.              FailurePoint50:
  1825.                 Limit = ArrayGetLength(TrackObj->FrameArray);
  1826.                 for (Scan = 0; Scan < Limit; Scan += 1)
  1827.                     {
  1828.                         DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(
  1829.                             TrackObj->FrameArray,Scan));
  1830.                     }
  1831.                 goto FailurePoint49;
  1832.             }
  1833.         TrackObj->BackgroundObjects = NewArray();
  1834.         if (TrackObj->BackgroundObjects == NIL)
  1835.             {
  1836.                 Error = eFileLoadOutOfMemory;
  1837.              FailurePoint51:
  1838.                 DisposeArray(TrackObj->DependentViews);
  1839.                 goto FailurePoint50;
  1840.             }
  1841.         NullTerminated = BlockToStringCopy(TrackObj->Name);
  1842.         if (NullTerminated == NIL)
  1843.             {
  1844.                 Error = eFileLoadOutOfMemory;
  1845.              FailurePoint52:
  1846.                 goto FailurePoint51;
  1847.             }
  1848.         TrackObj->TrackMenuItem = MakeNewMenuItem(TrackListGetTrackMenu(TrackList),
  1849.             NullTerminated,0);
  1850.         if (TrackObj->TrackMenuItem == NIL)
  1851.             {
  1852.                 Error = eFileLoadOutOfMemory;
  1853.              FailurePoint52a:
  1854.                 ReleasePtr(NullTerminated);
  1855.                 goto FailurePoint52;
  1856.             }
  1857.         ReleasePtr(NullTerminated);
  1858.         TrackObj->TrackWindow = NIL;
  1859.         TrackObj->CodeCenter = CodeCenter;
  1860.         TrackObj->MainWindow = MainWindow;
  1861.         TrackObj->TrackList = TrackList;
  1862.  
  1863.         *ObjectOut = TrackObj;
  1864.         return eFileLoadNoError;
  1865.     }
  1866.  
  1867.  
  1868. /* write the track information to the file. */
  1869. FileLoadingErrors            TrackObjectWriteDataOut(TrackObjectRec* TrackObj,
  1870.                                                 struct BufferedOutputRec* Output)
  1871.     {
  1872.         char*                                StringTemp;
  1873.         FileLoadingErrors        Error;
  1874.  
  1875.         CheckPtrExistence(TrackObj);
  1876.         CheckPtrExistence(Output);
  1877.  
  1878.         /*   1-byte format version number */
  1879.         /*       should be 1 */
  1880.         if (!WriteBufferedUnsignedChar(Output,1))
  1881.             {
  1882.                 return eFileLoadDiskError;
  1883.             }
  1884.  
  1885.         /*   2-byte little endian window X position (signed; from top-left corner of screen) */
  1886.         /* if the window is open when the file is saved, then the most recent location */
  1887.         /* of the window will not be saved. */
  1888.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowXLoc))
  1889.             {
  1890.                 return eFileLoadDiskError;
  1891.             }
  1892.  
  1893.         /*   2-byte little endian window Y position */
  1894.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowYLoc))
  1895.             {
  1896.                 return eFileLoadDiskError;
  1897.             }
  1898.  
  1899.         /*   2-byte little endian window width */
  1900.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowWidth))
  1901.             {
  1902.                 return eFileLoadDiskError;
  1903.             }
  1904.  
  1905.         /*   2-byte little endian window height */
  1906.         if (!WriteBufferedSignedShortLittleEndian(Output,TrackObj->SavedWindowHeight))
  1907.             {
  1908.                 return eFileLoadDiskError;
  1909.             }
  1910.  
  1911.         /*   4-byte little endian track name length descriptor */
  1912.         StringTemp = TrackObjectGetNameCopy(TrackObj);
  1913.         if (StringTemp == NIL)
  1914.             {
  1915.                 return eFileLoadOutOfMemory;
  1916.             }
  1917.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  1918.             {
  1919.                 ReleasePtr(StringTemp);
  1920.                 return eFileLoadDiskError;
  1921.             }
  1922.  
  1923.         /*   n-byte track name string (line feed = 0x0a) */
  1924.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  1925.             {
  1926.                 ReleasePtr(StringTemp);
  1927.                 return eFileLoadDiskError;
  1928.             }
  1929.         ReleasePtr(StringTemp);
  1930.  
  1931.         /*   4-byte little endian large integer coded decimal default early/late adjust */
  1932.         /*       large integer coded decimal is decimal * 1000000 with a */
  1933.         /*       range of -1999.999999 to 1999.999999 */
  1934.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1935.             Double2LargeBCD(TrackObjectGetEarlyLateAdjust(TrackObj))))
  1936.             {
  1937.                 return eFileLoadDiskError;
  1938.             }
  1939.  
  1940.         /*   4-byte little endian large integer coded decimal default release point 1 */
  1941.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1942.             Double2LargeBCD(TrackObjectGetReleasePoint1(TrackObj))))
  1943.             {
  1944.                 return eFileLoadDiskError;
  1945.             }
  1946.  
  1947.         /*   1-byte default release point 1 mode flag */
  1948.         /*       0 = release from start */
  1949.         /*       1 = release from end */
  1950.         switch (TrackObjectGetReleasePoint1StartEndFlag(TrackObj))
  1951.             {
  1952.                 default:
  1953.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  1954.                         "from TrackObjectGetReleasePoint1StartEndFlag"));
  1955.                     break;
  1956.                 case eRelease1FromStart:
  1957.                     if (!WriteBufferedUnsignedChar(Output,0))
  1958.                         {
  1959.                             return eFileLoadDiskError;
  1960.                         }
  1961.                     break;
  1962.                 case eRelease1FromEnd:
  1963.                     if (!WriteBufferedUnsignedChar(Output,1))
  1964.                         {
  1965.                             return eFileLoadDiskError;
  1966.                         }
  1967.                     break;
  1968.             }
  1969.  
  1970.         /*   4-byte little endian large integer coded decimal default release point 2 */
  1971.         if (!WriteBufferedSignedLongLittleEndian(Output,
  1972.             Double2LargeBCD(TrackObjectGetReleasePoint2(TrackObj))))
  1973.             {
  1974.                 return eFileLoadDiskError;
  1975.             }
  1976.  
  1977.         /*   1-byte default release point 2 mode flag */
  1978.         /*       0 = release from start */
  1979.         /*       1 = release from end */
  1980.         switch (TrackObjectGetReleasePoint2StartEndFlag(TrackObj))
  1981.             {
  1982.                 default:
  1983.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  1984.                         "from TrackObjectGetReleasePoint2StartEndFlag"));
  1985.                     break;
  1986.                 case eRelease2FromStart:
  1987.                     if (!WriteBufferedUnsignedChar(Output,0))
  1988.                         {
  1989.                             return eFileLoadDiskError;
  1990.                         }
  1991.                     break;
  1992.                 case eRelease2FromEnd:
  1993.                     if (!WriteBufferedUnsignedChar(Output,1))
  1994.                         {
  1995.                             return eFileLoadDiskError;
  1996.                         }
  1997.                     break;
  1998.             }
  1999.  
  2000.         /*   4-byte little endian large integer coded decimal default overall loudness */
  2001.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2002.             Double2LargeBCD(TrackObjectGetOverallLoudness(TrackObj))))
  2003.             {
  2004.                 return eFileLoadDiskError;
  2005.             }
  2006.  
  2007.         /*   4-byte little endian large integer coded decimal default stereo positioning */
  2008.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2009.             Double2LargeBCD(TrackObjectGetStereoPositioning(TrackObj))))
  2010.             {
  2011.                 return eFileLoadDiskError;
  2012.             }
  2013.  
  2014.         /*   4-byte little endian large integer coded decimal default surround positioning */
  2015.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2016.             Double2LargeBCD(TrackObjectGetSurroundPositioning(TrackObj))))
  2017.             {
  2018.                 return eFileLoadDiskError;
  2019.             }
  2020.  
  2021.         /*   4-byte little endian large integer coded decimal default accent 1 */
  2022.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2023.             Double2LargeBCD(TrackObjectGetAccent1(TrackObj))))
  2024.             {
  2025.                 return eFileLoadDiskError;
  2026.             }
  2027.  
  2028.         /*   4-byte little endian large integer coded decimal default accent 2 */
  2029.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2030.             Double2LargeBCD(TrackObjectGetAccent2(TrackObj))))
  2031.             {
  2032.                 return eFileLoadDiskError;
  2033.             }
  2034.  
  2035.         /*   4-byte little endian large integer coded decimal default accent 3 */
  2036.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2037.             Double2LargeBCD(TrackObjectGetAccent3(TrackObj))))
  2038.             {
  2039.                 return eFileLoadDiskError;
  2040.             }
  2041.  
  2042.         /*   4-byte little endian large integer coded decimal default accent 4 */
  2043.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2044.             Double2LargeBCD(TrackObjectGetAccent4(TrackObj))))
  2045.             {
  2046.                 return eFileLoadDiskError;
  2047.             }
  2048.  
  2049.         /*   4-byte little endian large integer coded decimal default pitch disp depth adjust */
  2050.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2051.             Double2LargeBCD(TrackObjectGetPitchDisplacementDepthAdjust(TrackObj))))
  2052.             {
  2053.                 return eFileLoadDiskError;
  2054.             }
  2055.  
  2056.         /*   1-byte default pitch displacement depth adjust mode flag */
  2057.         /*       0 = half steps */
  2058.         /*       1 = hertz */
  2059.         switch (TrackObjectGetPitchDisplacementDepthControlFlag(TrackObj))
  2060.             {
  2061.                 default:
  2062.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2063.                         "from TrackObjectGetPitchDisplacementDepthControlFlag"));
  2064.                     break;
  2065.                 case ePitchDisplacementDepthModeHalfSteps:
  2066.                     if (!WriteBufferedUnsignedChar(Output,0))
  2067.                         {
  2068.                             return eFileLoadDiskError;
  2069.                         }
  2070.                     break;
  2071.                 case ePitchDisplacementDepthModeHertz:
  2072.                     if (!WriteBufferedUnsignedChar(Output,1))
  2073.                         {
  2074.                             return eFileLoadDiskError;
  2075.                         }
  2076.                     break;
  2077.             }
  2078.  
  2079.         /*   4-byte little endian large integer coded decimal default pitch disp rate adjust */
  2080.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2081.             Double2LargeBCD(TrackObjectGetPitchDisplacementRateAdjust(TrackObj))))
  2082.             {
  2083.                 return eFileLoadDiskError;
  2084.             }
  2085.  
  2086.         /*   4-byte little endian large integer coded decimal default pitch disp start point */
  2087.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2088.             Double2LargeBCD(TrackObjectGetPitchDisplacementStartPoint(TrackObj))))
  2089.             {
  2090.                 return eFileLoadDiskError;
  2091.             }
  2092.  
  2093.         /*   1-byte default pitch displacement start point mode flag */
  2094.         /*       0 = pitch displacement point from start */
  2095.         /*       1 = pitch displacement point from end */
  2096.         switch (TrackObjectGetPitchDisplacementFromStartOrEnd(TrackObj))
  2097.             {
  2098.                 default:
  2099.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2100.                         "from TrackObjectGetPitchDisplacementFromStartOrEnd"));
  2101.                     break;
  2102.                 case ePitchDisplacementStartFromStart:
  2103.                     if (!WriteBufferedUnsignedChar(Output,0))
  2104.                         {
  2105.                             return eFileLoadDiskError;
  2106.                         }
  2107.                     break;
  2108.                 case ePitchDisplacementStartFromEnd:
  2109.                     if (!WriteBufferedUnsignedChar(Output,1))
  2110.                         {
  2111.                             return eFileLoadDiskError;
  2112.                         }
  2113.                     break;
  2114.             }
  2115.  
  2116.         /*   4-byte little endian large integer coded decimal default hurry-up factor */
  2117.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2118.             Double2LargeBCD(TrackObjectGetHurryUp(TrackObj))))
  2119.             {
  2120.                 return eFileLoadDiskError;
  2121.             }
  2122.  
  2123.         /*   4-byte little endian large integer coded decimal default detuning */
  2124.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2125.             Double2LargeBCD(TrackObjectGetDetune(TrackObj))))
  2126.             {
  2127.                 return eFileLoadDiskError;
  2128.             }
  2129.  
  2130.         /*   1-byte default detuning mode flag */
  2131.         /*       0 = half steps */
  2132.         /*       1 = hertz */
  2133.         switch (TrackObjectGetDetuneControlFlag(TrackObj))
  2134.             {
  2135.                 default:
  2136.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2137.                         "from TrackObjectGetDetuneControlFlag"));
  2138.                     break;
  2139.                 case eDetuningModeHalfSteps:
  2140.                     if (!WriteBufferedUnsignedChar(Output,0))
  2141.                         {
  2142.                             return eFileLoadDiskError;
  2143.                         }
  2144.                     break;
  2145.                 case eDetuningModeHertz:
  2146.                     if (!WriteBufferedUnsignedChar(Output,1))
  2147.                         {
  2148.                             return eFileLoadDiskError;
  2149.                         }
  2150.                     break;
  2151.             }
  2152.  
  2153.         /*   4-byte little endian large integer coded decimal default duration */
  2154.         if (!WriteBufferedSignedLongLittleEndian(Output,
  2155.             Double2LargeBCD(TrackObjectGetDurationAdjust(TrackObj))))
  2156.             {
  2157.                 return eFileLoadDiskError;
  2158.             }
  2159.  
  2160.         /*   1-byte default duration mode flag */
  2161.         /*       0 = duration adjust is multiplicative */
  2162.         /*       1 = duration adjust is additive */
  2163.         switch (TrackObjectGetDurationModeFlag(TrackObj))
  2164.             {
  2165.                 default:
  2166.                     EXECUTE(PRERR(ForceAbort,"TrackObjectWriteDataOut:  bad value "
  2167.                         "from TrackObjectGetDurationModeFlag"));
  2168.                     break;
  2169.                 case eDurationAdjustMultiplicative:
  2170.                     if (!WriteBufferedUnsignedChar(Output,0))
  2171.                         {
  2172.                             return eFileLoadDiskError;
  2173.                         }
  2174.                     break;
  2175.                 case eDurationAdjustAdditive:
  2176.                     if (!WriteBufferedUnsignedChar(Output,1))
  2177.                         {
  2178.                             return eFileLoadDiskError;
  2179.                         }
  2180.                     break;
  2181.             }
  2182.  
  2183.         /*   1-byte flag for playback inclusion */
  2184.         /*       0 = don't play track in final playback */
  2185.         /*       1 = do play track in final playback */
  2186.         if (TrackObjectShouldItBePlayed(TrackObj))
  2187.             {
  2188.                 if (!WriteBufferedUnsignedChar(Output,1))
  2189.                     {
  2190.                         return eFileLoadDiskError;
  2191.                     }
  2192.             }
  2193.          else
  2194.             {
  2195.                 if (!WriteBufferedUnsignedChar(Output,0))
  2196.                     {
  2197.                         return eFileLoadDiskError;
  2198.                     }
  2199.             }
  2200.  
  2201.         /*   4-byte little endian instrument name string length descriptor */
  2202.         StringTemp = TrackObjectGetInstrName(TrackObj);
  2203.         if (StringTemp == NIL)
  2204.             {
  2205.                 return eFileLoadOutOfMemory;
  2206.             }
  2207.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2208.             {
  2209.                 ReleasePtr(StringTemp);
  2210.                 return eFileLoadDiskError;
  2211.             }
  2212.  
  2213.         /*   n-byte instrument name string (line feed = 0x0a) */
  2214.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2215.             {
  2216.                 ReleasePtr(StringTemp);
  2217.                 return eFileLoadDiskError;
  2218.             }
  2219.         ReleasePtr(StringTemp);
  2220.  
  2221.         /*   1-byte flag for channel post processing enabling */
  2222.         /*       0 = don't do channel postprocessing */
  2223.         /*       1 = do channel postprocessing */
  2224.         if (TrackObj->PostProcessingEnable)
  2225.             {
  2226.                 if (!WriteBufferedUnsignedChar(Output,1))
  2227.                     {
  2228.                         return eFileLoadDiskError;
  2229.                     }
  2230.             }
  2231.          else
  2232.             {
  2233.                 if (!WriteBufferedUnsignedChar(Output,0))
  2234.                     {
  2235.                         return eFileLoadDiskError;
  2236.                     }
  2237.             }
  2238.  
  2239.         /*   4-byte little endian postprocessing expression length descriptor */
  2240.         StringTemp = TrackObjectGetPostProcessing(TrackObj);
  2241.         if (StringTemp == NIL)
  2242.             {
  2243.                 return eFileLoadOutOfMemory;
  2244.             }
  2245.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2246.             {
  2247.                 ReleasePtr(StringTemp);
  2248.                 return eFileLoadDiskError;
  2249.             }
  2250.  
  2251.         /*   n-bytes of postprocessing stuff (line feed = 0x0a) */
  2252.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2253.             {
  2254.                 ReleasePtr(StringTemp);
  2255.                 return eFileLoadDiskError;
  2256.             }
  2257.         ReleasePtr(StringTemp);
  2258.  
  2259.         /*   n-bytes of data for note array */
  2260.         Error = WriteNoteVector(TrackObj->FrameArray,Output);
  2261.         if (Error != eFileLoadNoError)
  2262.             {
  2263.                 return Error;
  2264.             }
  2265.  
  2266.         return eFileLoadNoError;
  2267.     }
  2268.  
  2269.  
  2270. /* mark track object as saved */
  2271. void                                    TrackObjectMarkAsSaved(TrackObjectRec* TrackObj)
  2272.     {
  2273.         CheckPtrExistence(TrackObj);
  2274.         /* there is no state data in the window */
  2275.         TrackObj->DataModified = False;
  2276.     }
  2277.  
  2278.  
  2279. /* make the track object write out the note array to the file */
  2280. MyBoolean                            TrackObjectWriteNotesOutToFile(TrackObjectRec* TrackObj,
  2281.                                                 struct BufferedOutputRec* Output)
  2282.     {
  2283.         CheckPtrExistence(TrackObj);
  2284.         CheckPtrExistence(Output);
  2285.         return (eFileLoadNoError == WriteNoteVector(TrackObj->FrameArray,Output));
  2286.     }
  2287.  
  2288.  
  2289. /* load notes from the file & replace track's notes with them */
  2290. MyBoolean                            TrackObjectRecoverNotesFromFile(TrackObjectRec* TrackObj,
  2291.                                                 struct BufferedInputRec* Input)
  2292.     {
  2293.         ArrayRec*                        NewNoteVector EXECUTE(= (ArrayRec*)0x81818181);
  2294.         long                                Limit;
  2295.         long                                Scan;
  2296.  
  2297.         CheckPtrExistence(TrackObj);
  2298.         CheckPtrExistence(Input);
  2299.         /* get the new vector */
  2300.         if (eFileLoadNoError != ReadNoteVector(&NewNoteVector,Input))
  2301.             {
  2302.                 return False;
  2303.             }
  2304.         CheckPtrExistence(NewNoteVector);
  2305.         /* delete the old one */
  2306.         Limit = ArrayGetLength(TrackObj->FrameArray);
  2307.         for (Scan = 0; Scan < Limit; Scan += 1)
  2308.             {
  2309.                 DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(
  2310.                     TrackObj->FrameArray,Scan));
  2311.             }
  2312.         DisposeArray(TrackObj->FrameArray);
  2313.         /* install the new one */
  2314.         TrackObj->FrameArray = NewNoteVector;
  2315.         TrackObjectAltered(TrackObj,0);
  2316.         return True;
  2317.     }
  2318.